﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Utils;
using System.Collections.ObjectModel;
using ConfigDialog.Model;
using System.Windows.Input;
using System.IO;
using System.Windows.Data;
using System.Windows;
using System.Xml.Linq;

namespace ConfigDialog.ViewModel
{
	class MainWindow : ViewModelBase
	{
		private ObservableCollection<Media> m_pendingList;
		public ObservableCollection<Media> PendingList
		{
			get
			{
				return (m_pendingList);
			}
			set
			{
				if (value != m_pendingList)
				{
					m_pendingList = value;
					this.OnPropertyChanged("PendingList");
				}
			}
		}
		private Media m_selectedPendingMedia;
		public Media SelectedPendingMedia
		{
			get
			{
				return (m_selectedPendingMedia);
			}
			set
			{
				if (value != m_selectedPendingMedia)
				{
					m_selectedPendingMedia = value;
					this.OnPropertyChanged("SelectedPendingMedia");
				}
			}
		}
		private Media m_selectedMedia;
		public Media SelectedMedia
		{
			get
			{
				return (m_selectedMedia);
			}
			set
			{
				if (value != m_selectedMedia)
				{
					m_selectedMedia = value;
					this.OnPropertyChanged("SelectedMedia");
				}
			}
		}
		private ObservableCollection<Media> m_mediaList;
		public ObservableCollection<Media> MediaList
		{
			get
			{
				return (m_mediaList);
			}
			set
			{
				if (value != m_mediaList)
				{
					m_mediaList = value;
					this.OnPropertyChanged("MediaList");
				}
			}
		}
		private ICommand m_commandAddFile;
		public ICommand CommandAddFile
		{
			get
			{
				if (m_commandAddFile == null)
					m_commandAddFile = new RelayCommand<object>(this.AddFile, this.CanAddFile);
				return (m_commandAddFile);
			}
		}
		private ICommand m_commandAddFolder;
		public ICommand CommandAddFolder
		{
			get
			{
				if (m_commandAddFolder == null)
					m_commandAddFolder = new RelayCommand<object>(this.AddFolder, this.CanAddFolder);
				return (m_commandAddFolder);
			}
		}
		private ICommand m_commandImport;
		public ICommand CommandImport
		{
			get
			{
				if (m_commandImport == null)
					m_commandImport = new RelayCommand<object>(this.Import, this.CanImport);
				return (m_commandImport);
			}
		}
		private ICommand m_commandImportAll;
		public ICommand CommandImportAll
		{
			get
			{
				if (m_commandImportAll == null)
					m_commandImportAll = new RelayCommand<object>(this.ImportAll, this.CanImportAll);
				return (m_commandImportAll);
			}
		}
		private ICommand m_commandRemove;
		public ICommand CommandRemove
		{
			get
			{
				if (m_commandRemove == null)
					m_commandRemove = new RelayCommand<object>(this.Remove, this.CanRemove);
				return (m_commandRemove);
			}
		}
		private ICommand m_commandRemoveAll;
		public ICommand CommandRemoveAll
		{
			get
			{
				if (m_commandRemoveAll == null)
					m_commandRemoveAll = new RelayCommand<object>(this.RemoveAll, this.CanRemoveAll);
				return (m_commandRemoveAll);
			}
		}
		private ICommand m_commandSave;
		public ICommand CommandSave
		{
			get
			{
				if (m_commandSave == null)
					m_commandSave = new RelayCommand<object>(this.Save, this.CanSave);
				return (m_commandSave);
			}
		}

		private void LoadMedias()
		{
			if (File.Exists("playlist.xml"))
			{
				try
				{
					XDocument xmlDoc = XDocument.Load("playlist.xml");
					XElement root = xmlDoc.Element("Playlist");
					var medias = (from m in root.Elements("Media")
								  select new Media
								  {
									  Path = m.Element("Path").Value,
									  Name = m.Element("Name").Value,
									  Style = m.Element("Style").Value
								  });
					var collection = new ObservableCollection<Media>();
					foreach (Media m in medias)
						collection.Add(m);
					MediaList = collection;
				}
				catch (Exception e)
				{
					MessageBox.Show("Error: " + e.Message);
				}
			}
		}

		public MainWindow()
		{
			m_pendingList = new ObservableCollection<Media>();
			m_mediaList = new ObservableCollection<Media>();
			this.LoadMedias();
		}

		bool CanAddFile(object _parameter)
		{
			return (true);
		}
		void AddFile(object _parameter)
		{
			Stream myStream = null;
			Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();
			openFileDialog.Filter = "All files (*.mp3)|*.mp3";
			openFileDialog.RestoreDirectory = true;
			if (openFileDialog.ShowDialog() == true)
			{
				try
				{
					if ((myStream = openFileDialog.OpenFile()) != null)
					{
						var tmp = new ObservableCollection<Media>(PendingList);
						tmp.Add(new Media { Path = openFileDialog.FileName, Name = openFileDialog.SafeFileName, Style = "None" });
						PendingList = tmp;
						myStream.Close();
					}
				}
				catch (Exception e)
				{
					System.Windows.MessageBox.Show("Error: Can't open the file " + openFileDialog.FileName + " (" + e.Message + ")");
				}
			}
		}

		bool CanAddFolder(object _parameter)
		{
			return (true);
		}
		void AddFolder(object _parameter)
		{
			var openFileDialog = new System.Windows.Forms.FolderBrowserDialog();
			if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
			{
				try
				{
					var tmp = new ObservableCollection<Media>(PendingList);
					foreach (string f in Directory.GetFiles(openFileDialog.SelectedPath, "*.mp3"))
					{
						FileStream myStream = File.Open(f, FileMode.Open);
						tmp.Add(new Media { Path = f, Name = Path.GetFileName(f), Style = "Jazz" });
						myStream.Close();
					}
					PendingList = tmp;
				}
				catch (Exception e)
				{
					System.Windows.MessageBox.Show("Error: Can't open the file " + openFileDialog.SelectedPath + " (" + e.Message + ")");
				}
			}
		}

		bool CanImport(object _parameter)
		{
			return (m_selectedPendingMedia != null);
		}
		void Import(object _parameter)
		{
			Media source = m_selectedPendingMedia;

			m_pendingList.Remove(source);
			m_mediaList.Add(source);
		}

		bool CanImportAll(object _parameter)
		{
			return (m_pendingList.Count > 0);
		}
		void ImportAll(object _parameter)
		{
			foreach (Media m in m_pendingList)
				m_mediaList.Add(m);
			m_pendingList.Clear();
		}

		bool CanRemove(object _parameter)
		{
			return (m_selectedMedia != null);
		}
		void Remove(object _parameter)
		{
			Media source = m_selectedMedia;

			m_mediaList.Remove(source);
			m_pendingList.Add(source);
		}

		bool CanRemoveAll(object _parameter)
		{
			return (m_mediaList.Count > 0);
		}
		void RemoveAll(object _parameter)
		{
			foreach (Media m in m_mediaList)
				m_pendingList.Add(m);
			m_mediaList.Clear();
		}

		bool CanSave(object _parameter)
		{
			return (true);
		}
		void Save(object _parameter)
		{
			XElement root = new XElement("Playlist");
			foreach (Media m in MediaList)
			{
				XElement c = new XElement("Media");
				c.Add(new XElement("Path", m.Path));
				c.Add(new XElement("Name", m.Name));
				c.Add(new XElement("Style", m.Style));
				root.Add(c);
			}
			XDocument doc = new XDocument(new XDeclaration("1.0", "utf-8", "yes"), root);
			FileStream f = File.OpenWrite("playlist.xml");
			f.SetLength(0);
			doc.Save(f);
			f.Close();
		}
	}

	public class NullToBoolConverter : IValueConverter
	{
		#region IValueConverter Members

		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			return ((value != null));
		}

		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			return (null);
		}

		#endregion
	}
}
